Atelier programmation de jeux vidéos en processing

Atelier Programmation en processing: feuille de route: version "pong"

Introduction

Que va-t-on apprendre au cours de cet atelier ?

Qu’est-ce que processing ?

Qu’allons-nous programmer ?

../data/pong1.png../data/pong2.png

La programmation proprement dite

Etape 1: la création de l’écran de jeu

void setup() {
   // ce qui sera exécuté une seule fois lorsque le programme est lancé
   size(800,600);
}
 
void draw() {
   // ce qui est exécuté toutes les 1/30 secondes 

   fill(255,0,0); // à ajouter ensuite en expliquant le rvb
   rect(10,10,100,200); // à ajouter en donnant les primitives

   fill(128,128,0);
   ellipse(300,300,50,50);
}

Etape 2: la balle

float balle_x = 10;
float balle_y = 10;

void setup() {
   size(800,600);
}

void draw() {
   fill(128,128,0);
   ellipse(balle_x,balle_y,10,10);

   balle_x = balle_x + 1;
   balle_y = balle_y + 1;
}
float balle_x = 10;
float balle_y = 10;
float dep_x = 1; // modifier en démo
float dep_y = 1;

void setup() {
   size(800,600);
}

void draw() {
   background(0); // à ajouter après
   fill(128,128,0);
   ellipse(balle_x,balle_y,10,10);

   balle_x = balle_x + dep_x;
   balle_y = balle_y + dep_y;

   if (balle_x<0 || balle_x>800) {dep_x=-dep_x;}
   if (balle_y<0 || balle_y>800) {dep_y=-dep_y;}
}

Etape 3: la raquette

float balle_x = 10;
float balle_y = 10;
float dep_x = 2;
float dep_y = 1;

void setup() {
   size(800,600);
}

void draw() {
   background(0); // à ajouter après
   fill(128,128,0);
   ellipse(balle_x,balle_y,10,10);

   balle_x = balle_x + dep_x;
   balle_y = balle_y + dep_y;

   if (balle_x<0 || balle_x>800) {dep_x=-dep_x;}
   if (balle_y<0 || balle_y>800) {dep_y=-dep_y;}

   fill(0,0,255);
   rect(10,mouseY,10,100);
}
float balle_x = 10;
float balle_y = 10;
float dep_x = 2;
float dep_y = 1;

void setup() {
  size(800, 600);
}

void draw() {
  background(0);
  fill(128, 128, 0);
  ellipse(balle_x, balle_y, 10, 10);

  fill(0, 0, 255);
  rect(10, mouseY, 10, 100);

  if (balle_x > 10 && balle_x < 20 && balle_y > mouseY && balle_y < mouseY + 100) {
    dep_x = -dep_x;
  }

  balle_x = balle_x + dep_x;
  balle_y = balle_y + dep_y;

  if (balle_x < 0 || balle_x > 800) {
    dep_x = -dep_x;
  }
  if (balle_y < 0 || balle_y > 600) {
    dep_y = -dep_y;
  }
}

Etape 4: Fin de partie, on relance

float balle_x = 100;
float balle_y = 10;
float dep_x = 2;
float dep_y = 1;

void setup() {
  size(800, 600);
}

void draw() {
  background(0);
  fill(128, 128, 0);
  ellipse(balle_x, balle_y, 10, 10);

  fill(0, 0, 255);
  rect(10, mouseY, 10, 100);

  if (balle_x > 10 && balle_x < 20 && balle_y > mouseY && balle_y < mouseY + 100) {
    dep_x = -dep_x;
  }

  balle_x = balle_x + dep_x;
  balle_y = balle_y + dep_y;

  if (balle_x > 800) {
    dep_x = -dep_x;
  }
  if (balle_y < 0 || balle_y > 600) {
    dep_y = -dep_y;
  }
  if (balle_x<10) {
    balle_x=random(300)+100;
    balle_y=random(300)+100;
    dep_x=3*random(100)/100; // un réel [0,3]
    dep_y=6*random(100)/100-3; // un réel [-3, 3]    
  }
}

A cette étape, on a un jeu terminé !

Quelques améliorations maintenant.

Compter les scores la balle accélère à chaque rebond temps de latence dans la raquette

float balle_x = 100;
float balle_y = 10;
float dep_x = 2;
float dep_y = 1;
float raquette_y=0;
int nbballes=0;
float vitesse=1;

void setup() {
  size(800, 600);
}

void draw() {
  // à ajouter si exécution sur environnement programmation js
  fill(255,255,255);
  rect(0,0,1500,1000);

  background(100);
  fill(128, 128, 0);
  ellipse(balle_x, balle_y, 10, 10);

  fill(0, 0, 255);
  rect(10, raquette_y, 10, 100);

  raquette_y=raquette_y+(mouseY-raquette_y)/10;
  
  if (balle_x > 10 && balle_x < 20 && balle_y > raquette_y && balle_y < raquette_y + 100) {
    dep_x = -dep_x;
  }

  balle_x = balle_x + vitesse*dep_x;
  balle_y = balle_y + vitesse*dep_y;

  if (balle_x > 800) {
    dep_x = -dep_x;
    vitesse=vitesse*1.1;
  }
  if (balle_y < 0 || balle_y > 600) {
    dep_y = -dep_y;
  }
  if (balle_x<10) {
    balle_x=random(300)+100;
    balle_y=random(300)+100;
    dep_x=3*random(100)/100; // un réel [0,3]
    dep_y=6*random(100)/100-3; // un réel [-3, 3]
    nbballes=nbballes+1;
    vitesse=1;
  }
  
  fill(255);
  text(nbballes+" balles perdues !",10,550);
}

Atelier Programmation en processing: feuille de route: version "raquette"

Introduction

Que va-t-on apprendre au cours de cet atelier ?

Qu’est-ce que processing ?

Qu’allons-nous programmer ?

La programmation proprement dite

Etape 1: la création de l’écran de jeu

void setup() {
   // ce qui sera exécuté une seule fois lorsque le programme est lancé
   size(800,600);
}

void draw() {
   // ce qui est exécuté toutes les 1/30 secondes

   fill(255,0,0); // à ajouter ensuite en expliquant le rvb
   rect(10,10,100,200); // à ajouter en donnant les primitives 

   fill(128,128,0);
   ellipse(300,300,50,50);
}

Etape 2: la balle

float balle_x = 10;
float balle_y = 10;

void setup() {
   size(800,600);
}

void draw() {
   fill(128,128,0);
   ellipse(balle_x,balle_y,10,10);

   balle_x = balle_x + 1;
   balle_y = balle_y + 1;
}
float balle_x = 10;
float balle_y = 10;
float dep_x = 1; // modifier en démo
float dep_y = 1;

void setup() {
   size(800,600);
}

void draw() {
   background(0); // à ajouter après
   fill(128,128,0);
   ellipse(balle_x,balle_y,10,10);

   balle_x = balle_x + dep_x;
   balle_y = balle_y + dep_y;

   if (balle_x<0 || balle_x>800) {dep_x=-dep_x;}
   if (balle_y<0 || balle_y>800) {dep_y=-dep_y;}
}

Etape 3: la raquette version carrée

float balle_x = 10;
float balle_y = 10;
float dep_x = 2;
float dep_y = 1;

void setup() {
   size(800,600);
}

void draw() {
   background(0); // à ajouter après
   fill(128,128,0);
   ellipse(balle_x,balle_y,10,10); 

   balle_x = balle_x + dep_x;
   balle_y = balle_y + dep_y; 

   if (balle_x<0 || balle_x>800) {dep_x=-dep_x;}
   if (balle_y<0 || balle_y>800) {dep_y=-dep_y;}

   fill(0,0,255);
   rect(mouseX,mouseY,50,50);
}

Si la raquette est carrée, elle se comporte un peu comme un bord !

float balle_x = 10;
float balle_y = 10;
float dep_x = 2;
float dep_y = 1;

void setup() {
  size(800, 600);
}

void draw() {
  background(0);
  fill(128, 128, 0);
  ellipse(balle_x, balle_y, 10, 10); 

  fill(0, 0, 255);
  rect(mouseX, mouseY, 50, 50); 

  if (balle_x > mouseX && balle_x < mouseX + 50 && balle_y > mouseY && balle_y < mouseY + 50) {
    // La balle est dans la raquette (mais a-t-elle tapé en horizontal ou en vertical) ?
    if (min(abs(balle_x - mouseX), abs(balle_x - mouseX - 50)) < min(abs(balle_y - mouseY), abs(balle_y - mouseY - 50))) {
      dep_x = -dep_x;
    } else {
      dep_y = -dep_y;
    }
  }

  balle_x = balle_x + dep_x;
  balle_y = balle_y + dep_y;

  if (balle_x < 0 || balle_x > 800) {
    dep_x = -dep_x;
  }
  if (balle_y < 0 || balle_y > 600) {
    dep_y = -dep_y;
  }
}

Etape 4: la cible

float balle_x = 10;
float balle_y = 10;
float dep_x = 2;
float dep_y = 1;

float cible_x=0;
float cible_y=0;
float taille=0;

int nbtouchees = 0;

void setup() {
  size(1400, 1000);
}

void draw() {
  background(100);
  fill(128, 128, 0);
  ellipse(balle_x, balle_y, 10, 10);

  fill(0, 0, 255);
  rect(mouseX, mouseY, 50, 50);

  fill(0,255,0);
  rect(cible_x,cible_y,taille,taille);
  
  if (balle_x > mouseX && balle_x < mouseX + 50 && balle_y > mouseY && balle_y < mouseY + 50) {
    // La balle est dans la raquette (mais a-t-elle tapé en horizontal ou en vertical) ?
    if (min(abs(balle_x - mouseX), abs(balle_x - mouseX - 50)) < min(abs(balle_y - mouseY), abs(balle_y - mouseY - 50))) {
      dep_x = -dep_x;
    } else {
      dep_y = -dep_y;
    }
  }

  balle_x = balle_x + dep_x;
  balle_y = balle_y + dep_y;

  if (balle_x < 0 || balle_x > 800) {
    dep_x = -dep_x;
  }
  if (balle_y < 0 || balle_y > 600) {
    dep_y = -dep_y;
  }
 
  taille = taille - 0.1;
 
  if (taille <= 0) {
    cible_x=random(700);
    cible_y=random(500);
    taille = 100;
  }
 
  if (balle_x > cible_x && balle_x < cible_x + taille && balle_y > cible_y && balle_y < cible_y + taille) {
    cible_x=random(700);
    cible_y=random(500);
    taille = 100;
    nbtouchees = nbtouchees + 1;    
  }

  fill(255,255,255);
  text(nbtouchees + " cibles touchées ! ", 10, 550);
}

A cette étape, on a un jeu terminé !

Quelques améliorations maintenant.

la raquette ronde.

../data/raquette.png

On connaît:

On veut connaître V2=(dep’_x,dep’_y)

On commence par calculer pscal=V1 . BR (produit scalaire)

Ensuite et simplement:

Affichage du temps écoulé

float balle_x = 10;
float balle_y = 10;
float dep_x = 2;
float dep_y = 1;

float cible_x = 0;
float cible_y = 0;
float taille = 0;

int nbtouchees = 0;

int tdebut=minute()*60+second();

void setup() {
  size(1400, 1000);
}

void draw() {
  background(100);
  fill(128, 128, 0);
  ellipse(balle_x, balle_y, 10, 10); 

  fill(0, 0, 255);
  ellipse(mouseX, mouseY, 100, 100);

  fill(0, 255, 0);
  rect(cible_x, cible_y, taille, taille);

  float distance = sqrt((mouseX - balle_x) * (mouseX - balle_x) + (mouseY - balle_y) * (mouseY - balle_y));

  if (distance < 55) {
    float normx = (mouseX - balle_x) / distance;
    float normy = (mouseY - balle_y) / distance;
    float pscal = dep_x * normx + dep_y * normy;
    dep_x = dep_x - 2 * pscal * normx;
    dep_y = dep_y - 2 * pscal * normy;
  }
 
 
  balle_x = balle_x + dep_x;
  balle_y = balle_y + dep_y;
 
 
  if (balle_x < 0 || balle_x > 800) {
    dep_x = -dep_x;
  }
  if (balle_y < 0 || balle_y > 600) {
    dep_y = -dep_y;
  }

  taille = taille - 0.1;

  if (taille <= 0) {
    cible_x = random(700);
    cible_y = random(500);
    taille = 100;
  }

  if (balle_x > cible_x && balle_x < cible_x + taille && balle_y > cible_y && balle_y < cible_y + taille) {
    cible_x = random(700);
    cible_y = random(500);
    taille = 100;
    nbtouchees = nbtouchees + 1;
  }
  fill(255, 255, 255);
  text(nbtouchees + " cibles touchées en " +(minute()*60+second()-tdebut)+ " secondes ! ", 10, 550);
}

un peu de latence dans le déplacement de la raquette

float balle_x = 10;
float balle_y = 10;
float dep_x = 2;
float dep_y = 1;

float cible_x = 0;
float cible_y = 0;
float taille = 0;

float raquette_x=0; raquette_y=0; 

int nbtouchees = 0; 

int tdebut=minute()*60+second();

void setup() {
  size(800, 600);
}

void draw() {
  // à ajouter si exécution sur environnement programmation js
  fill(255,255,255);
  rect(0,0,1500,1000);

  background(100);
  fill(128, 128, 0);
  ellipse(balle_x, balle_y, 10, 10);

  // latence dans le déplacement
  raquette_x = raquette_x+(mouseX-raquette_x)/10;
  raquette_y = raquette_y+(mouseY-raquette_y)/10;
 
  fill(0, 0, 255);
  ellipse(raquette_x, raquette_y, 100, 100);

  fill(0, 255, 0);
  rect(cible_x, cible_y, taille, taille);

  float distance = sqrt((raquette_x - balle_x) * (raquette_x - balle_x) + (raquette_y - balle_y) * (raquette_y - balle_y));

  if (distance < 55) {
    float normx = (raquette_x - balle_x) / distance;
    float normy = (raquette_y - balle_y) / distance;
    float pscal = dep_x * normx + dep_y * normy;
    dep_x = dep_x - 2 * pscal * normx;
    dep_y = dep_y - 2 * pscal * normy;
  }
 
 
  balle_x = balle_x + dep_x;
  balle_y = balle_y + dep_y;
 
 
  if (balle_x < 0 || balle_x > 800) {
    dep_x = -dep_x;
  }
  if (balle_y < 0 || balle_y > 600) {
    dep_y = -dep_y;
  }

  taille = taille - 0.1;

  if (taille <= 0) {
    cible_x = random(700);
    cible_y = random(500);
    taille = 100;
  }

  if (balle_x > cible_x && balle_x < cible_x + taille && balle_y > cible_y && balle_y < cible_y + taille) {
    cible_x = random(700);
    cible_y = random(500);
    taille = 100;
    nbtouchees = nbtouchees + 1;
  }
  fill(255, 255, 255);
  text(nbtouchees + " cibles touchées en " +(minute()*60+second()-tdebut)+ " secondes ! ", 10, 550);
}

Un petit délai avant de pouvoir frapper la balle

float balle_x = 10;
float balle_y = 10;
float dep_x = 2;
float dep_y = 1;

float cible_x = 0;
float cible_y = 0;
float taille = 0;

float raquette_x=0;
float raquette_y=0;
int possible=0;

int nbtouchees = 0;

int tdebut=minute()*60+second();

void setup() {
  size(800, 600);
}

void draw() {
  // à ajouter si exécution sur environnement programmation js
  fill(255,255,255);
  rect(0,0,1500,1000);

  background(100);
  fill(128, 128, 0);
  ellipse(balle_x, balle_y, 10, 10);

  // latence dans le déplacement
  raquette_x = raquette_x+(mouseX-raquette_x)/10;
  raquette_y = raquette_y+(mouseY-raquette_y)/10;
 
  fill((possible < 0)?255:0, max(0, 2*possible), 255, 128);
  ellipse(raquette_x, raquette_y, 100, 100);

  fill(0, 255, 0);
  rect(cible_x, cible_y, taille, taille);

  float distance = sqrt((raquette_x - balle_x) * (raquette_x - balle_x) + (raquette_y - balle_y) * (raquette_y - balle_y));

  if (distance < 55 && possible < 0) {
    float normx = (raquette_x - balle_x) / distance;
    float normy = (raquette_y - balle_y) / distance;
    float pscal = dep_x * normx + dep_y * normy;
    dep_x = dep_x - 2 * pscal * normx;
    dep_y = dep_y - 2 * pscal * normy;
    possible = 100;
  }
  possible--;
 
  balle_x = balle_x + dep_x;
  balle_y = balle_y + dep_y;
 
  if (balle_x < 0 || balle_x > 800) {
    dep_x = -dep_x;
  }
  if (balle_y < 0 || balle_y > 600) {
    dep_y = -dep_y;
  }

  taille = taille - 0.1;

  if (taille <= 0) {
    cible_x = random(700);
    cible_y = random(500);
    taille = 100;
  }

  if (balle_x > cible_x && balle_x < cible_x + taille && balle_y > cible_y && balle_y < cible_y + taille) {
    cible_x = random(700);
    cible_y = random(500);
    taille = 100;
    nbtouchees = nbtouchees + 1;
  }
  fill(255, 255, 255);
  text(nbtouchees + " cibles touchées en "+(minute()*60+second()-tdebut)+" secondes !", 10, 550);
}